package view;

import dao.DataManager;
import model.*;
import util.CinemaUtil;
import util.InputUtil;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class FrontDeskView {
    private final DataManager dataManager;
    private final User currentUser;

    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");

    public FrontDeskView(User currentUser) {
        this.dataManager = DataManager.getInstance();
        this.currentUser = currentUser;
    }

    public void showMenu() {
        while (true) {
            System.out.println("\n===== 前台菜单 =====");
            System.out.println("1. 查看影片信息");
            System.out.println("2. 查看场次信息");
            System.out.println("3. 查看座位信息");
            System.out.println("4. 售票");
            System.out.println("5. 退票");
            System.out.println("6. 修改密码");
            System.out.println("7. 退出登录");
            System.out.print("请选择操作: ");

            int choice = InputUtil.readIntRange("", 1, 7);

            switch (choice) {
                case 1:
                    listAllMovies();
                    break;
                case 2:
                    listAllScreenings();
                    break;
                case 3:
                    showSeatInfo();
                    break;
                case 4:
                    sellTicket();
                    break;
                case 5:
                    refundTicket();
                    break;
                case 6:
                    changePassword();
                    break;
                case 7:
                    System.out.println("已退出前台账户");
                    return;
            }
        }
    }

    private void listAllMovies() {
        System.out.println("\n===== 正在上映影片列表 =====");
        List<Movie> movies = dataManager.getAllMovies();

        if (movies.isEmpty()) {
            System.out.println("当前没有影片信息");
        } else {
            for (int i = 0; i < movies.size(); i++) {
                System.out.println("\n影片 " + (i + 1) + ":");
                System.out.println(movies.get(i));
                System.out.println("-------------------------------");
            }
        }

        InputUtil.pressEnterToContinue();
    }

    private void listAllScreenings() {
        System.out.println("\n===== 场次列表 =====");
        System.out.println("1. 查看当日场次");
        System.out.println("2. 查看3日内场次");
        System.out.println("3. 查看一周内场次");

        int choice = InputUtil.readIntRange("请选择: ", 1, 3);

        List<Screening> screenings;
        switch (choice) {
            case 1:
                screenings = CinemaUtil.getTodayScreenings();
                System.out.println("\n===== 当日场次 =====");
                break;
            case 2:
                screenings = CinemaUtil.getThreeDayScreenings();
                System.out.println("\n===== 3日内场次 =====");
                break;
            case 3:
                screenings = CinemaUtil.getWeekScreenings();
                System.out.println("\n===== 一周内场次 =====");
                break;
            default:
                screenings = new ArrayList<>();
        }

        CinemaUtil.printScreenings(screenings);
        InputUtil.pressEnterToContinue();
    }

    private void showSeatInfo() {
        System.out.println("\n===== 座位信息 =====");

        // 获取所有场次
        List<Screening> allScreenings = CinemaUtil.getWeekScreenings();
        if (allScreenings.isEmpty()) {
            System.out.println("当前没有可查看的场次");
            return;
        }

        // 选择电影
        List<Movie> movies = dataManager.getAllMovies();
        System.out.println("\n请选择电影：");
        CinemaUtil.printMovies(movies);
        int movieIndex = InputUtil.readIntRange("请输入电影编号(0表示不限): ", 0, movies.size());

        Movie selectedMovie = null;
        List<Screening> filteredScreenings = allScreenings;

        if (movieIndex > 0) {
            selectedMovie = movies.get(movieIndex - 1);
            final Movie movie = selectedMovie; // 为lambda表达式创建final引用
            filteredScreenings = allScreenings.stream()
                    .filter(s -> s.getMovie().getId().equals(movie.getId())).collect(Collectors.toList());
        }

        if (filteredScreenings.isEmpty()) {
            System.out.println("没有找到该电影的场次");
            return;
        }

        // 显示筛选后的场次
        System.out.println("\n可选场次：");
        CinemaUtil.printScreenings(filteredScreenings);

        int screeningIndex = InputUtil.readIntRange("请选择场次编号: ", 1, filteredScreenings.size());
        Screening selectedScreening = filteredScreenings.get(screeningIndex - 1);

        // 显示座位信息
        System.out.println("\n===== 座位信息 =====");
        System.out.println("电影：" + selectedScreening.getMovie().getTitle());
        System.out.println("场次：" + selectedScreening.getStartTime().format(DATE_TIME_FORMATTER));
        System.out.println("放映厅：" + selectedScreening.getHall().getName());
        System.out.println("总座位数：" + selectedScreening.getHall().getTotalSeats());
        System.out.println("空闲座位数：" + selectedScreening.getAvailableSeats());
        System.out.println("\n座位图（O表示空闲，X表示已售）：");

        CinemaUtil.printSeats(selectedScreening.getSeats());

        InputUtil.pressEnterToContinue();
    }

    private void sellTicket() {
        System.out.println("\n===== 售票 =====");

        // 获取所有场次
        List<Screening> allScreenings = CinemaUtil.getWeekScreenings();
        if (allScreenings.isEmpty()) {
            System.out.println("当前没有可售票的场次");
            return;
        }

        // 选择电影和场次
        List<Movie> movies = dataManager.getAllMovies();
        System.out.println("\n请选择电影：");
        CinemaUtil.printMovies(movies);
        int movieIndex = InputUtil.readIntRange("请输入电影编号(0表示不限): ", 0, movies.size());

        Movie selectedMovie = null;
        List<Screening> filteredScreenings = allScreenings;

        if (movieIndex > 0) {
            selectedMovie = movies.get(movieIndex - 1);
            final Movie movie = selectedMovie; // 为lambda表达式创建final引用
            filteredScreenings = allScreenings.stream()
                    .filter(s -> s.getMovie().getId().equals(movie.getId()))
                    .collect(Collectors.toList());
        }

        if (filteredScreenings.isEmpty()) {
            System.out.println("没有找到该电影的场次");
            return;
        }

        // 显示筛选后的场次
        System.out.println("\n可选场次：");
        CinemaUtil.printScreenings(filteredScreenings);

        int screeningIndex = InputUtil.readIntRange("请选择场次编号: ", 1, filteredScreenings.size());
        Screening selectedScreening = filteredScreenings.get(screeningIndex - 1);

        // 检查电影是否已经开始
        if (selectedScreening.getStartTime().isBefore(LocalDateTime.now())) {
            System.out.println("该场次已经开始放映，无法售票！");
            return;
        }

        // 显示座位图
        System.out.println("\n座位图（O表示空闲，X表示已售）：");
        CinemaUtil.printSeats(selectedScreening.getSeats());

        // 选择座位
        System.out.println("\n请输入要购买的座位（多个座位用空格分隔，如：3 5 表示购买第3排第5座）");
        int ticketCount = InputUtil.readIntRange("请输入要购买的票数: ", 1, 10);

        List<int[]> selectedSeats = new ArrayList<>();
        for (int i = 0; i < ticketCount; i++) {
            while (true) {
                int row = InputUtil.readIntRange("请输入第" + (i + 1) + "张票的排数: ", 1, selectedScreening.getHall().getRows()) - 1;
                int seat = InputUtil.readIntRange("请输入第" + (i + 1) + "张票的座位号: ", 1, selectedScreening.getHall().getSeatsPerRow()) - 1;

                // 检查座位是否已售
                if (selectedScreening.isSeatOccupied(row, seat)) {
                    System.out.println("该座位已售出，请重新选择！");
                    continue;
                }

                // 检查是否已选择过该座位
                boolean seatAlreadySelected = false;
                for (int[] seat1 : selectedSeats) {
                    if (seat1[0] == row && seat1[1] == seat) {
                        seatAlreadySelected = true;
                        break;
                    }
                }

                if (seatAlreadySelected) {
                    System.out.println("该座位已被您选择，请重新选择！");
                    continue;
                }

                // 添加选中的座位
                selectedSeats.add(new int[]{row, seat});
                break;
            }
        }

        // 计算票价
        double totalPrice = ticketCount * selectedScreening.getPrice();
        System.out.println("\n总票价: " + totalPrice + " 元");

        // 确认售票
        boolean confirm = InputUtil.readBoolean("确认购票？");
        if (!confirm) {
            System.out.println("售票已取消！");
            return;
        }

        // 创建票
        List<Ticket> tickets = new ArrayList<>();
        for (int[] seat : selectedSeats) {
            Ticket ticket = new Ticket(selectedScreening, seat[0], seat[1]);
            tickets.add(ticket);

            // 标记座位为已售
            selectedScreening.setSeat(seat[0], seat[1], true);
        }

        // 保存票据和更新场次信息
        for (Ticket ticket : tickets) {
            dataManager.addTicket(ticket);
        }
        dataManager.updateScreening(selectedScreening);

        // 打印票据信息
        System.out.println("\n===== 票据信息 =====");
        for (int i = 0; i < tickets.size(); i++) {
            System.out.println("\n票据 " + (i + 1) + ":");
            System.out.println(tickets.get(i));
            System.out.println("----------------------------");
        }

        System.out.println("\n售票成功！请保存好电子票号，退票时需使用。");
        InputUtil.pressEnterToContinue();
    }

    private void refundTicket() {
        System.out.println("\n===== 退票 =====");

        String ticketId = InputUtil.readNonEmptyString("请输入电子票号: ");
        Ticket ticket = dataManager.getTicketById(ticketId);

        if (ticket == null) {
            System.out.println("未找到该票！");
            return;
        }

        if (ticket.getStatus() != TicketStatus.VALID) {
            System.out.println("该票已" + ticket.getStatus() + "，无法退票！");
            return;
        }

        if (!ticket.canRefund()) {
            System.out.println("该票已超过退票时间（开场前1小时），无法退票！");
            return;
        }

        System.out.println("\n票据信息：");
        System.out.println(ticket);

        boolean confirm = InputUtil.readBoolean("确认退票？");
        if (!confirm) {
            System.out.println("退票已取消！");
            return;
        }

        // 退票操作
        ticket.setStatus(TicketStatus.REFUNDED);
        dataManager.updateTicket(ticket);

        // 释放座位
        Screening screening = ticket.getScreening();
        screening.setSeat(ticket.getRow(), ticket.getSeat(), false);
        dataManager.updateScreening(screening);

        System.out.println("退票成功！");
        InputUtil.pressEnterToContinue();
    }

    private void changePassword() {
        System.out.println("\n===== 修改密码 =====");

        String oldPassword = InputUtil.readNonEmptyString("请输入当前密码: ");
        if (!oldPassword.equals(currentUser.getPassword())) {
            System.out.println("当前密码不正确，无法修改密码！");
            return;
        }

        String newPassword = InputUtil.readNonEmptyString("请输入新密码: ");
        String confirmPassword = InputUtil.readNonEmptyString("请再次输入新密码: ");

        if (!newPassword.equals(confirmPassword)) {
            System.out.println("两次输入的密码不一致，无法修改密码！");
            return;
        }

        currentUser.setPassword(newPassword);
        currentUser.setNeedResetPassword(false);
        dataManager.updateUser(currentUser);

        System.out.println("密码修改成功！");
    }
}
